package com.wxproject.demo.Controller;
import com.wxproject.demo.Common.lang.ResultBody;
import com.wxproject.demo.Common.lang.ResultMap;
import com.wxproject.demo.Entity.LoginEntity;
import com.wxproject.demo.Entity.UserEntity;
import com.wxproject.demo.Entity.VO.ReSetPasswordVO;
import com.wxproject.demo.Service.LoginService;
import com.wxproject.demo.Service.RoleService;
import com.wxproject.demo.Utils.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Controller
@RestController
public class LoginController {
    @Autowired
    private EmailUtil emailUtil;
    @Autowired
    private RoleService userMapper;
    @Autowired
    private ResultMap resultMap;
    @Autowired
    private LoginCountUtil loginCountUtil;
    @Autowired
    private LoginService loginService;
    @PostMapping("/login")
    public Map<Object,Object> login(@Validated @RequestBody LoginEntity userEntity) {
        String realPassword = userMapper.getPassword(userEntity.getUsername());
        Map<Object,Object> map = new HashMap<>();
        Map<Object, Object> resmap = loginCountUtil.LoginCountCheck(userEntity, realPassword);
        if (resmap!=null) {
            return resmap;
        }
        map.put("code",400);
        map.put("message","网络错误");
        return map;
    }

    //如果返回一个Token则证明freshToken有效,如果返回两个，就证明freshToken失效，把前端缓存中的freshToken和Token替换为返回的值
    @GetMapping("/getToken")
    public ResultBody getToken(@RequestParam("freshToken")String freshToken, @RequestParam("Token")String Token){
        String username = JWTUtil.getUsername(freshToken);
        String jwtId = UUID.randomUUID().toString();
        String jwtId1 = JWTUtil.getJwtId(freshToken);
        String userId =JWTUtil.getUserId(Token);
        if (JWTUtil.getUsername(freshToken).equals(JWTUtil.getUsername(Token))&&JWTUtil.getJwtId(freshToken).equals(JWTUtil.getJwtId(Token))){
            if (JWTUtil.verify(freshToken)){
                return ResultBody.ok().message("freshToken有效，刷新Token").data("Token",JWTUtil.createToken(jwtId1,userId, username));
            }else {
                return ResultBody.ok().message("freshToken已失效，替换Token和freshToken").data("Token",JWTUtil.createToken(jwtId,userId,username)).data("freshToken",JWTUtil.createToken(jwtId,userId,username));
            }
        }
        return ResultBody.error().message("Token被篡改");
    }


    @PostMapping("/register")
    public ResultMap register(@Validated @RequestBody UserEntity userEntity) {
        UserEntity user = userEntity;
        userEntity.setPassword(MD5Utils.code(userEntity.getPassword()));
        Long id = SnowFlake.nextId();
        user.setId(id);
        if(loginService.checkEmail(userEntity.getEmail())!=null){
            return resultMap.fail().code(400).message("邮箱已被注册");
        }
            try {
                if (userMapper.register(userEntity) != 0) {
                    emailUtil.SendEmail(userEntity.getEmail(), id);
                    return resultMap.success().code(200).message("注册成功，请查看邮箱激活账户，有效期30分钟");
                }
            } catch (RuntimeException e) {
                throw new RuntimeException("用户已存在");
            }

        return resultMap.fail().code(400).message("网络错误");
    }

    @GetMapping(path = "/unauthorized/{message}")
    public ResultMap unauthorized(@PathVariable String message) {
        System.out.println("Controller:105"+message);
        return resultMap.success().code(401).message(message);
    }

    //添加Token黑名单
    @PostMapping("/logout")
    public ResultMap logoutAuth(HttpServletRequest httpServletRequest){
        String token = httpServletRequest.getHeader("Token");
        RedisUtil.del(JWTUtil.getUserId(token));
        RedisUtil.set(JWTUtil.getUserId(token),new Date(),1728000);
        return resultMap.success().code(200).message("注销成功");
    }

    @PostMapping("/ResetPassword")
    public ResultMap resetPassword(@RequestBody UserEntity userEntity){
        String id = String.valueOf(SnowFlake.nextId());
        Integer integer = emailUtil.changePassword(userEntity.getEmail(), id);
        if (integer==null){
            return resultMap.fail().code(400).message("用户名或邮箱不存在");
        }
        return resultMap.success().code(200).message("发送成功，请及时查收");
    }

    @PostMapping("/verify")
    public Map<String, Object> verifyCode(@RequestParam String codeId){
        Object o = RedisUtil.get("changePasswordId-"+codeId);
        System.out.println(o);
        if (o==null){
            return resultMap.fail().code(401).message("链接已失效");
        }
        RedisUtil.del("changePasswordId-"+codeId);
        String verifyId = UUID.randomUUID().toString();
        RedisUtil.set(verifyId,o.toString());
        Map<String,Object> res = new HashMap<>();
        res.put("code",200);
        res.put("verifyId",verifyId);
        res.put("message","验证成功");
        return res;
    }

    @PostMapping("/changePassword")
    public ResultMap changePassword(@RequestBody ReSetPasswordVO reSetPasswordVO){
        Object o = RedisUtil.get(reSetPasswordVO.getVerifyId());
        if (o==null){
            return resultMap.fail().message("verifyId不存在");
        }
        String email = RedisUtil.get(reSetPasswordVO.getVerifyId()).toString();
        String userID = loginService.getUserIdByEmail(email);
        Integer res = loginService.changePassword(MD5Utils.code(reSetPasswordVO.getPassword()),email);
        if (res!=0){
            RedisUtil.del(reSetPasswordVO.getVerifyId());
            RedisUtil.del(userID);
            RedisUtil.set(userID,new Date(),1728000);
            return resultMap.success().code(200).message("密码修改成功！");
        }
        return resultMap.fail().code(401).message("网络异常");
    }

    @ApiOperation(value = "desc of methoud",notes = "")
    @GetMapping("/getUserss")
    public void getUserss(){
        loginService.getUsers();
    }


    @RequestMapping("/test")
    public Map<Object,Object> testss(){
        Map<Object, Object> res = new HashMap<>();
        res.put("code",200);
        res.put("message","访问成功");
        return res;
    }
    @RequestMapping("/deleteRolesvalues2")
    public void dleeteRolesvalues2(){
        loginService.deleteRoles2();
    }
}
